#include "stdafx.h"
#include "popup.h"

#include <gtl/string/str.h>

namespace gtl
{

namespace skins
{

#define WM_WindowEvent WM_USER + 1101

popup::popup()
{
	m_hEventHook = NULL;
}

popup::~popup()
{
	if(m_hEventHook != NULL)
		UnhookWinEvent(m_hEventHook);
}

BEGIN_MESSAGE_MAP(popup, wnd)
	ON_WM_NCHITTEST()
	ON_MESSAGE(WM_WindowEvent, OnWindowEvent)
END_MESSAGE_MAP()

static void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook,
						   DWORD event,
						   HWND hwnd,
						   LONG idObject,
						   LONG idChild,
						   DWORD dwEventThread,
						   DWORD dwmsEventTime)   
{
	switch(event)
	{
	case EVENT_OBJECT_SHOW:
		SendMessage(hwnd, WM_WindowEvent, SW_SHOW, NULL);
		break;

	case EVENT_OBJECT_HIDE:
		SendMessage(hwnd, WM_WindowEvent, SW_HIDE, NULL);
		break;

	default:
		break;
	}
}

unsigned int popup::initialize(gtl::xml& node, wnd* parent_wnd)
{
	std::vector<gtl::tstr> vecClasses;
	vecClasses.push_back(_T("hittest"));
	node.filters(vecClasses);

	const gtl::xml::nodes_type& rects = node.xpath(_T("/hittest/*"));
	for(gtl::xml::const_iterator ite = rects.begin(); ite != rects.end(); ++ite)
	{
		CRect rcHitTest(0, 0, 0, 0);
		GetRect(rcHitTest, *(*ite));
		m_hittest_rects.push_back(rcHitTest);
	}

	return reinterpret_cast<unsigned long>(m_hWnd);
}

void popup::GetRect(CRect& rect, gtl::xml& node)
{
	rect.left = node(_T("x"), true);
	rect.top = node(_T("y"), true);
	rect.right = node(_T("width"), true);
	rect.bottom = node(_T("height"), true);

	rect.right += rect.left;
	rect.bottom += rect.top;
}

LRESULT popup::OnNcHitTest(CPoint point)
{
	LRESULT nHitTest = CWnd::OnNcHitTest(point);
	if(IsZoomed() || (GetStyle() & WS_CHILD))
		return nHitTest;

	ScreenToClient(&point);
	bool bHitTest = false;
	for(size_t i = 0; i < m_hittest_rects.size(); i++)
	{
		if(m_hittest_rects[i].PtInRect(point))
			bHitTest = true;
	}

	return (nHitTest == HTCLIENT && bHitTest) ? HTCAPTION : nHitTest;
}

LRESULT popup::OnWindowEvent(WPARAM wParam, LPARAM lParam)
{
	wnd* parent_wnd = GetParent();
	if(parent_wnd != NULL)
	{
		parent_wnd->EnableWindow(wParam == SW_SHOW ? FALSE : TRUE);
	}

	return 0;
}

} // end of namespace skins

} // end of namespace gtl